package com.toilet.easyvideofx.manager;

import com.toilet.easyvideofx.api.response.FileStreamResponse;
import com.toilet.easyvideofx.compent.RequestComponent;
import javafx.concurrent.Service;
import javafx.concurrent.Task;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

public class DownLoadFileService extends Service<Long> {
    /**
     * 开始大小
     */
    private Long startSize;
    /**
     * 总大小
     */
    private final Long downLoadSize;
    /**
     * 请求下载的id
     */
    private final Long downLoadId;
    /**
     * 文件名称
     */
    private final String fileName;


    public DownLoadFileService(Long startSize, Long downLoadSize,
                               Long downLoadId, String fileName) {
        this.startSize = startSize;
        this.downLoadSize = downLoadSize;
        this.downLoadId = downLoadId;
        this.fileName = fileName;
    }

    /**
     * 获取当前下载进度
     *
     * @return
     */
    public Long getCurrentSize() {
        return startSize;
    }

    @Override
    protected Task<Long> createTask() {

        //从服务端获取上传的块的大小
        int getUploadSize = RequestComponent.get("/operation_file/file_chunk_size", Integer.class, null);
        //若块比文件本身还大，则直接下载整个文件即可
        AtomicInteger chunkSize = new AtomicInteger(getUploadSize > downLoadSize ? downLoadSize.intValue() : getUploadSize);
        AtomicReference<String> downloadName = new AtomicReference<>();
        AtomicLong size = new AtomicLong(0L);
        return new Task<Long>() {
            @Override
            protected Long call() {
                while (startSize < downLoadSize) {
                    System.out.println("开始下载起始偏移量:" + startSize + " 块大小为:" + chunkSize.get());
                    Map<String, String> params = new HashMap<>();
                    params.put("fileId", downLoadId.toString());
                    params.put("currentSize", String.valueOf(startSize));
                    params.put("chunkSize", String.valueOf(chunkSize.get()));
                    FileStreamResponse streamResponse = RequestComponent.downloadStream(params, "/operation_file/file_stream_download");
                    System.out.println("响应数据为 " + streamResponse.fileName() + "--文件大小为 " + streamResponse.fileSize());
                    long getsize = size.get() + streamResponse.fileSize();
                    size.set(getsize);
                    System.out.println("当前大小为 " + size.get());

                    downloadName.set("E:\\杂物间\\下载\\" + streamResponse.fileName());
                    try (RandomAccessFile raf = new RandomAccessFile("E:\\杂物间\\下载\\" + streamResponse.fileName(), "rw")) {
                        byte[] bytes = streamResponse.stream().readAllBytes();
                        // 定位到该分片的偏移量
                        raf.seek(startSize);
                        // 写入
                        raf.write(bytes);
                        startSize += bytes.length;
                        //获取的后的大小
                        long getLength = startSize + chunkSize.get();
                        if (getLength > downLoadSize) {
                            chunkSize.set((int) (downLoadSize - startSize));
                        }
                        // 更新下载进度
                        updateProgress(startSize, downLoadSize);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                File file = new File(downloadName.get());
                boolean renameTo = file.renameTo(new File("E:\\杂物间\\下载\\" + fileName));
                System.out.println("重命名结果" + renameTo);
                return startSize;
            }
        };
    }
}
